[IA64] allow vcpu to move between pcpus
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 3 Jul 2006 14:53:02 +0000 (08:53 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 3 Jul 2006 14:53:02 +0000 (08:53 -0600)
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/vhpt.c
xen/include/asm-ia64/domain.h
xen/include/asm-ia64/vhpt.h

index f6b39d7dba2805bb2fa0871b87f716f74f87fd22..ec8f8601961ac74b55ad370a94a17afaf33adfa4 100644 (file)
@@ -92,6 +92,29 @@ DEFINE_PER_CPU(int *, current_psr_ic_addr);
 
 #include <xen/sched-if.h>
 
+static void flush_vtlb_for_context_switch(struct vcpu* vcpu)
+{
+       int last_vcpu_id =
+               vcpu->domain->arch.last_vcpu[smp_processor_id()].vcpu_id;
+
+       if (is_idle_domain(vcpu->domain) || last_vcpu_id == vcpu->vcpu_id)
+               return;
+       vcpu->domain->arch.last_vcpu[smp_processor_id()].vcpu_id =
+               vcpu->vcpu_id;
+       if (last_vcpu_id == INVALID_VCPU_ID) 
+               return;
+
+       // if the vTLB implementation was changed,
+       // the followings must be updated either.
+       if (VMX_DOMAIN(vcpu)) {
+               // currently vTLB for vt-i domian is per vcpu.
+               // so any flushing isn't needed.
+       } else {
+               vhpt_flush();
+       }
+       local_flush_tlb_all();
+}
+
 void schedule_tail(struct vcpu *prev)
 {
        extern char ia64_ivt;
@@ -110,6 +133,7 @@ void schedule_tail(struct vcpu *prev)
                __ia64_per_cpu_var(current_psr_ic_addr) = (int *)
                  (current->domain->arch.shared_info_va + XSI_PSR_IC_OFS);
        }
+       flush_vtlb_for_context_switch(current);
 }
 
 void context_switch(struct vcpu *prev, struct vcpu *next)
@@ -175,6 +199,7 @@ if (!i--) { i = 1000000; printk("+"); }
                __ia64_per_cpu_var(current_psr_ic_addr) = NULL;
         }
     }
+    flush_vtlb_for_context_switch(current);
     local_irq_restore(spsr);
     context_saved(prev);
 }
@@ -309,9 +334,14 @@ static void init_switch_stack(struct vcpu *v)
 
 int arch_domain_create(struct domain *d)
 {
+       int i;
+       
        // the following will eventually need to be negotiated dynamically
        d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR;
        d->arch.breakimm = 0x1000;
+       for (i = 0; i < NR_CPUS; i++) {
+               d->arch.last_vcpu[i].vcpu_id = INVALID_VCPU_ID;
+       }
 
        if (is_idle_domain(d))
            return 0;
index 3fe48facf7de0fcd1c71a3a8b20318fc023f2647..895e8bc0fe183d9af50e17cef4a4bfdeed1eb656 100644 (file)
@@ -23,7 +23,7 @@ extern long running_on_sim;
 DEFINE_PER_CPU (unsigned long, vhpt_paddr);
 DEFINE_PER_CPU (unsigned long, vhpt_pend);
 
-static void vhpt_flush(void)
+void vhpt_flush(void)
 {
        struct vhpt_lf_entry *v = __va(__ia64_per_cpu_var(vhpt_paddr));
        int i;
index d244e055e802202ce460e24309bef42cc5296e73..2f4b740eddc524836d217d5ab990ca3a16e9b882 100644 (file)
@@ -58,6 +58,11 @@ struct mm_struct {
     // atomic_t mm_users;                      /* How many users with user space? */
 };
 
+struct last_vcpu {
+#define INVALID_VCPU_ID INT_MAX
+    int vcpu_id;
+} ____cacheline_aligned_in_smp;
+
 struct arch_domain {
     struct mm_struct mm;
     unsigned long metaphysical_rr0;
@@ -101,6 +106,8 @@ struct arch_domain {
     void *efi_runtime;
     /* Metaphysical address to fpswa_interface_t in domain firmware memory is set. */
     void *fpswa_inf;
+
+    struct last_vcpu last_vcpu[NR_CPUS];
 };
 #define INT_ENABLE_OFFSET(v)             \
     (sizeof(vcpu_info_t) * (v)->vcpu_id + \
index 8823f1b56e3319104e76c3ad157e8cdf358c1707..6836ccafd13160990d0e44f259de3c0790016a07 100644 (file)
@@ -42,6 +42,7 @@ extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte,
                                 unsigned long logps);
 extern void vhpt_insert (unsigned long vadr, unsigned long pte,
                         unsigned long logps);
+void vhpt_flush(void);
 
 /* Currently the VHPT is allocated per CPU.  */
 DECLARE_PER_CPU (unsigned long, vhpt_paddr);